home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-03 | 24.9 KB | 1,162 lines |
- Newsgroups: comp.sources.unix
- From: davy@ecn.purdue.edu (Dave Curry)
- Subject: v25i092: getethers V1.0 - scan an ethernet and learn hostname/ethernet pairings
- Sender: sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: davy@ecn.purdue.edu (Dave Curry)
- Posting-Number: Volume 25, Issue 92
- Archive-Name: getethers
-
- This is GETETHERS Version 1.0. November, 1991
-
- GETETHERS runs through all the addresses on an ethernet (a.b.c.1 - a.b.c.254)
- and pings each address, and then determines the ethernet address for that host.
- It produces a list, either in ASCII or in the binary format for an Excelan
- Lanalyzer, of hostname/ethernet address pairs for all hosts on that network.
-
- This program has been tested on Sun workstations under SunOS 4.1.1. It may
- work on other systems with minor modifications, but I don't need it anywhere
- else, and haven't tried. It could be easily modified to generate files for
- other ethernet analyzer products (e.g., Sniffer), but since we don't have
- any of those, I don't feel real motivated to do it.
-
- If you make modifications or fixes, please send them to me for incorporation
- into future versions.
-
- Dave Curry
- Purdue University
- Engineering Computer Network
- davy@ecn.purdue.edu
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # getethers
- # This archive created: Wed Nov 27 10:57:56 1991
- export PATH; PATH=/bin:$PATH
- if test ! -d 'getethers'
- then
- echo shar: creating directory "'getethers'"
- mkdir 'getethers'
- fi
- echo shar: entering directory "'getethers'"
- cd 'getethers'
- echo shar: extracting "'main.c'" '(3986 characters)'
- if test -f 'main.c'
- then
- echo shar: will not over-write existing file "'main.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'main.c'
- X#ifndef lint
- Xstatic char *RCSid = "$Header: /usr/src/ecn/getethers/RCS/main.c,v 1.1 91/11/27 10:56:32 davy Exp $";
- X#endif
- X/*
- X * getethers - get hostname/ethernet address information for all hosts on
- X * an ethernet.
- X *
- X * David A. Curry
- X * Purdue University
- X * Engineering Computer Network
- X * davy@ecn.purdue.edu
- X * November, 1991
- X *
- X * $Log: main.c,v $
- X * Revision 1.1 91/11/27 10:56:32 davy
- X * Initial revision
- X *
- X */
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <arpa/inet.h>
- X#include <string.h>
- X#include <netdb.h>
- X#include <stdio.h>
- X#include "defs.h"
- X
- Xchar *pname;
- X
- Xmain(argc, argv)
- Xchar **argv;
- Xint argc;
- X{
- X char *p;
- X FILE *fp;
- X u_long network;
- X char *get_arp();
- X struct hostent *hp;
- X struct in_addr addr;
- X HostInfo hosts[MAXHOST];
- X char hname[64], fname[BUFSIZ];
- X int lna, verbose, writefile;
- X
- X pname = *argv;
- X verbose = writefile = 0;
- X
- X if (argc < 2)
- X usage();
- X
- X /*
- X * Get our hostname.
- X */
- X if (gethostname(hname, sizeof(hname)) < 0) {
- X error("gethostname");
- X exit(1);
- X }
- X
- X /*
- X * Process arguments.
- X */
- X while (--argc) {
- X /*
- X * Option.
- X */
- X if (**++argv == '-') {
- X switch (*++*argv) {
- X case 'v': /* verbose */
- X verbose = 1;
- X break;
- X case 'w': /* write files */
- X writefile = 1;
- X break;
- X default:
- X usage();
- X break;
- X }
- X
- X continue;
- X }
- X
- X /*
- X * Do *something*.
- X */
- X if (!verbose && !writefile)
- X verbose = 1;
- X
- X /*
- X * Convert the given network address to an internet
- X * address.
- X */
- X network = inet_network(*argv);
- X addr = inet_makeaddr(network, 0);
- X bzero(hosts, sizeof(hosts));
- X
- X /*
- X * Find the ethernet interface that's on that network.
- X */
- X if ((lna = check_if(addr, hosts)) < 0) {
- X fprintf(stderr, "%s: this host is not on the %s net.\n",
- X pname, inet_ntoa(addr));
- X continue;
- X }
- X
- X /*
- X * Save our hostname. check_if() filled in our
- X * internet address and ethernet address.
- X */
- X hosts[lna].hl_name = hname;
- X
- X if (verbose)
- X printf("%s:\n ", *argv);
- X
- X /*
- X * For each host...
- X */
- X for (lna = MINADDR; lna <= MAXADDR; lna++) {
- X if ((verbose == 1) && ((lna % 16) == 0)) {
- X printf("%d...", lna);
- X fflush(stdout);
- X }
- X
- X /*
- X * Skip our entry; we did it already.
- X */
- X if (hosts[lna].hl_name != NULL)
- X continue;
- X
- X /*
- X * Build the internet address.
- X */
- X addr = inet_makeaddr(network, lna);
- X
- X /*
- X * Ping it, and if it's up...
- X */
- X if (ping(addr, lna)) {
- X /*
- X * Get the hostname.
- X */
- X hp = gethostbyaddr(&addr.s_addr,
- X sizeof(addr.s_addr),
- X AF_INET);
- X
- X /*
- X * Save the hostname.
- X */
- X if (hp != NULL)
- X hosts[lna].hl_name = strdup(hp->h_name);
- X else
- X hosts[lna].hl_name = strdup("???");
- X
- X /*
- X * Save the internet address and get the
- X * ethernet address from the arp table.
- X */
- X hosts[lna].hl_inet = strdup(inet_ntoa(addr));
- X hosts[lna].hl_ether = get_arp(addr);
- X }
- X }
- X
- X if (verbose)
- X putchar('\n');
- X
- X /*
- X * If we need to write files, create the file for this
- X * network.
- X */
- X if (writefile) {
- X p = strrchr(*argv, '.') + 1;
- X sprintf(fname, "%snet.nam", p);
- X
- X if ((fp = fopen(fname, "w")) == NULL) {
- X error(fname);
- X exit(1);
- X }
- X
- X excelan_header(fp);
- X }
- X
- X /*
- X * Write or print each entry.
- X */
- X for (lna = MINADDR; lna <= MAXADDR; lna++) {
- X if (hosts[lna].hl_name == NULL)
- X continue;
- X
- X if (writefile)
- X excelan_entry(&hosts[lna], fp);
- X
- X if (verbose) {
- X printf("%s %s %s\n", hosts[lna].hl_name,
- X hosts[lna].hl_inet, hosts[lna].hl_ether);
- X }
- X
- X free(hosts[lna].hl_name);
- X free(hosts[lna].hl_inet);
- X free(hosts[lna].hl_ether);
- X }
- X
- X /*
- X * Write a footer and close the file.
- X */
- X if (writefile) {
- X excelan_footer(fp);
- X fclose(fp);
- X }
- X }
- X
- X exit(0);
- X}
- X
- X/*
- X * error - perror with program name.
- X */
- Xerror(s)
- Xchar *s;
- X{
- X fprintf(stderr, "%s: ", pname);
- X perror(s);
- X}
- X
- Xusage()
- X{
- X fprintf(stderr, "Usage: %s [-v] [-w] network [network...]\n", pname);
- X exit(1);
- X}
- SHAR_EOF
- if test 3986 -ne "`wc -c < 'main.c'`"
- then
- echo shar: error transmitting "'main.c'" '(should have been 3986 characters)'
- fi
- chmod +x 'main.c'
- fi # end of overwriting check
- echo shar: extracting "'Makefile'" '(658 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- sed 's/^X//' << \SHAR_EOF > 'Makefile'
- X#
- X# $Header: /usr/src/ecn/getethers/RCS/Makefile,v 1.1 91/11/27 10:56:07 davy Exp $
- X#
- X# Makefile for getethers.
- X#
- X# David A. Curry
- X# Purdue University
- X# Engineering Computer Network
- X# davy@ecn.purdue.edu
- X# November, 1991
- X#
- XBINDIR= /usr/ecn/etc
- XMANDIR= /usr/man/man8
- X
- XCFLAGS= -O
- X
- XOBJS= arp.o excelan.o if.o main.o ping.o
- X
- Xgetethers: $(OBJS)
- X $(CC) -o getethers $(OBJS)
- X
- Xinstall: getethers
- X install -c -s -m 4750 -o root -g wheel getethers $(BINDIR)/getethers
- X install -c -m 644 getethers.8l $(MANDIR)/getethers.8l
- X
- Xclean:
- X rm -f a.out core getethers *.o \#*
- X
- Xarp.o: arp.c
- Xexcelan.o: excelan.c defs.h
- Xmain.o: main.c defs.h
- Xif.o: if.c defs.h
- Xping.o: ping.c
- SHAR_EOF
- if test 658 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 658 characters)'
- fi
- chmod +x 'Makefile'
- fi # end of overwriting check
- echo shar: extracting "'defs.h'" '(892 characters)'
- if test -f 'defs.h'
- then
- echo shar: will not over-write existing file "'defs.h'"
- else
- sed 's/^X//' << \SHAR_EOF > 'defs.h'
- X/*
- X * $Header: /usr/src/ecn/getethers/RCS/defs.h,v 1.1 91/11/27 10:56:28 davy Exp $
- X *
- X * Definitions for getethers.
- X *
- X * David A. Curry
- X * Purdue University
- X * Engineering Computer Network
- X * davy@ecn.purdue.edu
- X * November, 1991
- X *
- X * $Log: defs.h,v $
- X * Revision 1.1 91/11/27 10:56:28 davy
- X * Initial revision
- X *
- X */
- X#define VERSION 1.0
- X
- X#define MAXHOST 256 /* max number of hosts to check */
- X#define MINADDR 1 /* minimum host number */
- X#define MAXADDR 254 /* maximum host number */
- X#define MAXPING 3 /* max number of pings to send */
- X#define PACKWAIT 1 /* min time to wait for packet */
- X#define MAXPACKET 4096 /* max packet size for ping */
- X#define FILESIZE 2584 /* size of lanalyzer file */
- X
- X/*
- X * Record for a host.
- X */
- Xtypedef struct {
- X char *hl_name; /* host name */
- X char *hl_inet; /* internet address */
- X char *hl_ether; /* ethernet address */
- X} HostInfo;
- SHAR_EOF
- if test 892 -ne "`wc -c < 'defs.h'`"
- then
- echo shar: error transmitting "'defs.h'" '(should have been 892 characters)'
- fi
- chmod +x 'defs.h'
- fi # end of overwriting check
- echo shar: extracting "'if.c'" '(2932 characters)'
- if test -f 'if.c'
- then
- echo shar: will not over-write existing file "'if.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'if.c'
- X#ifndef lint
- Xstatic char *RCSid = "$Header: /usr/src/ecn/getethers/RCS/if.c,v 1.1 91/11/27 10:56:31 davy Exp $";
- X#endif
- X
- X/*
- X * if.c - routines to check a system's ethernet interfaces.
- X *
- X * David A. Curry
- X * Purdue University
- X * Engineering Computer Network
- X * davy@ecn.purdue.edu
- X * November, 1991
- X *
- X * $Log: if.c,v $
- X * Revision 1.1 91/11/27 10:56:31 davy
- X * Initial revision
- X *
- X */
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <arpa/inet.h>
- X#include <sys/ioctl.h>
- X#include <sys/time.h>
- X#include <sys/file.h>
- X#include <net/if.h>
- X#include <net/nit_if.h>
- X#include <netinet/if_ether.h>
- X#include <string.h>
- X#include <stdio.h>
- X#include "defs.h"
- X
- X/*
- X * check_if - check our ethernet interfaces and find the one that's attached
- X * to the network in addr.
- X */
- Xcheck_if(addr, hosts)
- Xstruct in_addr addr;
- XHostInfo *hosts;
- X{
- X int n, s, lna;
- X char buf[BUFSIZ];
- X struct ifreq ifr;
- X struct ifconf ifc;
- X struct sockaddr *sad;
- X struct sockaddr_in *sin;
- X register struct ifreq *ifrp;
- X
- X /*
- X * Need a socket...
- X */
- X if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- X error("socket");
- X return(-1);
- X }
- X
- X ifc.ifc_buf = buf;
- X ifc.ifc_len = sizeof(buf);
- X
- X /*
- X * Get the list of configured interfaces.
- X */
- X if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) {
- X error("ioctl: SIOCGIFCONF");
- X close(s);
- X
- X return(-1);
- X }
- X
- X close(s);
- X
- X /*
- X * For each interface...
- X */
- X ifrp = ifc.ifc_req;
- X for (n = ifc.ifc_len/sizeof(struct ifreq); n > 0; n--, ifrp++) {
- X bcopy((char *) ifrp, (char *) &ifr, sizeof(struct ifreq));
- X
- X /*
- X * Need a new socket.
- X */
- X if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- X error("socket");
- X return(-1);
- X }
- X
- X /*
- X * Get the address of this interface.
- X */
- X if (ioctl(s, SIOCGIFADDR, (char *) &ifr) < 0) {
- X error("ioctl: SIOCGIFADDR");
- X close(s);
- X
- X return(-1);
- X }
- X
- X close(s);
- X
- X sin = (struct sockaddr_in *) &ifr.ifr_addr;
- X
- X /*
- X * If it's not the one we need, bag it.
- X */
- X if ((sin->sin_addr.s_addr & addr.s_addr) != addr.s_addr)
- X continue;
- X
- X /*
- X * Save the internet address, and keep the host byte.
- X * We are assuming a netmask of 255.255.255.0 here.
- X */
- X lna = inet_lnaof(sin->sin_addr) & 0xff;
- X hosts[lna].hl_inet = strdup(inet_ntoa(sin->sin_addr));
- X
- X /*
- X * Now we need the NIT, to get the ethernet address.
- X */
- X if ((s = open("/dev/nit", O_RDONLY)) < 0) {
- X error("open: /dev/nit");
- X return(-1);
- X }
- X
- X /*
- X * Bind the nit to this interface.
- X */
- X if (ioctl(s, NIOCBIND, (char *) ifrp) < 0) {
- X error("ioctl: NIOCBIND");
- X close(s);
- X
- X return(-1);
- X }
- X
- X /*
- X * Get the address.
- X */
- X if (ioctl(s, SIOCGIFADDR, (char *) ifrp) < 0) {
- X error("ioctl: SIOCGIFADDR");
- X close(s);
- X
- X return(-1);
- X }
- X
- X close(s);
- X
- X /*
- X * Save the ethernet address.
- X */
- X sad = (struct sockaddr *) &ifrp->ifr_addr;
- X hosts[lna].hl_ether = strdup(ether_ntoa((struct ether_addr *)
- X sad->sa_data));
- X
- X return(lna);
- X }
- X
- X return(-1);
- X}
- SHAR_EOF
- if test 2932 -ne "`wc -c < 'if.c'`"
- then
- echo shar: error transmitting "'if.c'" '(should have been 2932 characters)'
- fi
- chmod +x 'if.c'
- fi # end of overwriting check
- echo shar: extracting "'ping.c'" '(4113 characters)'
- if test -f 'ping.c'
- then
- echo shar: will not over-write existing file "'ping.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'ping.c'
- X#ifndef lint
- Xstatic char *RCSid = "$Header: /usr/src/ecn/getethers/RCS/ping.c,v 1.1 91/11/27 10:56:33 davy Exp $";
- X#endif
- X
- X/*
- X * ping.c - routines for pinging a host.
- X *
- X * David A. Curry
- X * Purdue University
- X * Engineering Computer Network
- X * davy@ecn.purdue.edu
- X * November, 1991
- X *
- X * $Log: ping.c,v $
- X * Revision 1.1 91/11/27 10:56:33 davy
- X * Initial revision
- X *
- X */
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <sys/file.h>
- X#include <netinet/in_systm.h>
- X#include <netinet/in.h>
- X#include <netinet/ip.h>
- X#include <netinet/ip_icmp.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X#include <netdb.h>
- X#include <errno.h>
- X#include <stdio.h>
- X#include "defs.h"
- X
- Xstatic jmp_buf env;
- Xstatic int ident;
- Xstatic int datalen = 64 - 8;
- Xstatic u_char inpacket[MAXPACKET], outpacket[MAXPACKET];
- X
- X/*
- X * ping - send ICMP ECHO REQUEST packets to the host at addr until it either
- X * responds or we decide to bag it. Most of this code was stolen and
- X * simplified from Mike Muuss' ping program.
- X */
- Xping(addr, id)
- Xstruct in_addr addr;
- Xint id;
- X{
- X int ringring();
- X register int i, n, s;
- X int cc, hlen, fromlen;
- X register u_char *datap;
- X register struct ip *ip;
- X register struct icmp *icp;
- X struct sockaddr_in from, to;
- X static struct protoent *proto = NULL;
- X
- X bzero((char *) &to, sizeof(struct in_addr));
- X
- X /*
- X * Construct destination address.
- X */
- X to.sin_family = AF_INET;
- X bcopy((char *) &addr, (char *) &to.sin_addr, sizeof(struct in_addr));
- X
- X /*
- X * ICMP ID number.
- X */
- X ident = (getpid() + id) & 0xFFFF;
- X
- X /*
- X * Look up protocol number.
- X */
- X if (proto == NULL) {
- X if ((proto = getprotobyname("icmp")) == NULL) {
- X error("icmp: unknown protocol");
- X return(0);
- X }
- X }
- X
- X /*
- X * Need a raw socket.
- X */
- X if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) {
- X error("socket");
- X return(0);
- X }
- X
- X icp = (struct icmp *) outpacket;
- X
- X /*
- X * Send up to MAXPING packets.
- X */
- X for (i=0; i < MAXPING; i++) {
- X /*
- X * Construct ICMP header.
- X */
- X icp->icmp_type = ICMP_ECHO;
- X icp->icmp_code = 0;
- X icp->icmp_cksum = 0;
- X icp->icmp_seq = i;
- X icp->icmp_id = ident;
- X
- X /*
- X * Stick some junk in the packet.
- X */
- X cc = datalen + 8;
- X datap = &outpacket[8];
- X
- X for (n = 0; n < datalen; n++)
- X *datap++ = n;
- X
- X /*
- X * Compute the IP checksum.
- X */
- X icp->icmp_cksum = in_cksum(icp, cc);
- X
- X /*
- X * Send the packet...
- X */
- X n = sendto(s, outpacket, cc, 0, &to, sizeof(struct sockaddr));
- X
- X if ((n < 0) || (n != cc)) {
- X if (n < 0)
- X error("sendto");
- X else
- X error("sendto truncated");
- X
- X close(s);
- X return(0);
- X }
- X
- X /*
- X * We'll wait for PACKWAIT seconds for a response.
- X */
- X signal(SIGALRM, ringring);
- X fromlen = sizeof(struct sockaddr_in);
- X
- X alarm(PACKWAIT);
- X
- X /*
- X * Bag it... send the next packet.
- X */
- X if (setjmp(env))
- X continue;
- X
- X /*
- X * Get the packet.
- X */
- X cc = recvfrom(s, inpacket, MAXPACKET, 0, &from, &fromlen);
- X alarm(0);
- X
- X if (cc < 0) {
- X if (errno == EINTR)
- X continue;
- X
- X error("recvfrom");
- X continue;
- X }
- X
- X /*
- X * Make sure it's a reply to ours.
- X */
- X ip = (struct ip *) inpacket;
- X hlen = ip->ip_hl << 2;
- X
- X if (cc < (hlen + ICMP_MINLEN))
- X continue;
- X
- X cc -= hlen;
- X icp = (struct icmp *) (&inpacket[hlen]);
- X
- X if (icp->icmp_type != ICMP_ECHOREPLY)
- X continue;
- X
- X if (icp->icmp_id != ident)
- X continue;
- X
- X /*
- X * Yay! The host is up.
- X */
- X close(s);
- X return(1);
- X }
- X
- X /*
- X * Boo! The host is down.
- X */
- X close(s);
- X return(0);
- X}
- X
- X/*
- X * in_cksum - compute the IP checksum.
- X */
- Xin_cksum(addr, len)
- Xu_short *addr;
- Xint len;
- X{
- X register u_short *w = addr;
- X register int nleft = len;
- X register u_short answer;
- X register int sum = 0;
- X
- X /*
- X * Use a 32-bit accumulator (sum) and add sequential 16-bit
- X * words to it, then fold back all the carry bits from the
- X * top 16 bits into the lower 16 bits.
- X */
- X while (nleft > 1) {
- X sum += *w++;
- X nleft -= 2;
- X }
- X
- X /*
- X * Pick up odd byte if necessary.
- X */
- X if (nleft == 1)
- X sum += *(u_char *) w;
- X
- X /*
- X * Add back the carry bits.
- X */
- X sum = (sum >> 16) + (sum & 0xFFFF);
- X sum += (sum >> 16);
- X
- X /*
- X * Truncate to 16 bits.
- X */
- X answer = ~sum;
- X
- X return(answer);
- X}
- X
- Xringring()
- X{
- X longjmp(env, 1);
- X}
- SHAR_EOF
- if test 4113 -ne "`wc -c < 'ping.c'`"
- then
- echo shar: error transmitting "'ping.c'" '(should have been 4113 characters)'
- fi
- chmod +x 'ping.c'
- fi # end of overwriting check
- echo shar: extracting "'arp.c'" '(1817 characters)'
- if test -f 'arp.c'
- then
- echo shar: will not over-write existing file "'arp.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'arp.c'
- X#ifndef lint
- Xstatic char *RCSid = "$Header: /usr/src/ecn/getethers/RCS/arp.c,v 1.1 91/11/27 10:56:13 davy Exp $";
- X#endif
- X
- X/*
- X * arp.c - routines for digging up arp table entries.
- X *
- X * David A. Curry
- X * Purdue University
- X * Engineering Computer Network
- X * davy@ecn.purdue.edu
- X * November, 1991
- X *
- X * $Log: arp.c,v $
- X * Revision 1.1 91/11/27 10:56:13 davy
- X * Initial revision
- X *
- X */
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <sys/ioctl.h>
- X#include <net/if.h>
- X#include <net/if_arp.h>
- X#include <netinet/if_ether.h>
- X#include <string.h>
- X#include <errno.h>
- X#include <stdio.h>
- X
- Xextern int errno;
- X
- X/*
- X * get_arp - get the arp table entry for the internet address in addr, and
- X * return the ethernet address as a character string.
- X */
- Xchar *
- Xget_arp(addr)
- Xstruct in_addr addr;
- X{
- X int s;
- X struct arpreq ar;
- X char *ether_ntoa();
- X struct sockaddr_in *sin;
- X
- X /*
- X * Clear the structure.
- X */
- X bzero((char *) &ar, sizeof(struct arpreq));
- X
- X /*
- X * We want internet family only.
- X */
- X ar.arp_pa.sa_family = AF_INET;
- X sin = (struct sockaddr_in *) &ar.arp_pa;
- X
- X /*
- X * Copy in the internet address.
- X */
- X sin->sin_family = AF_INET;
- X bcopy((char *) &addr, (char *) &sin->sin_addr, sizeof(struct sockaddr_in));
- X
- X /*
- X * Get a socket.
- X */
- X if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- X error("socket");
- X return(strdup("(unknown)"));
- X }
- X
- X /*
- X * Get the arp table entry.
- X */
- X if (ioctl(s, SIOCGARP, (char *) &ar) < 0) {
- X /*
- X * Nothing in the table.
- X */
- X if (errno == ENXIO) {
- X close(s);
- X return(strdup("(no entry)"));
- X }
- X
- X error("ioctl: SIOCGARP");
- X close(s);
- X
- X return("(unknown)");
- X }
- X
- X close(s);
- X
- X /*
- X * Is the entry complete?
- X */
- X if (ar.arp_flags & ATF_COM)
- X return(strdup(ether_ntoa((struct ether_addr *) ar.arp_ha.sa_data)));
- X
- X return(strdup("(incomplete)"));
- X}
- SHAR_EOF
- if test 1817 -ne "`wc -c < 'arp.c'`"
- then
- echo shar: error transmitting "'arp.c'" '(should have been 1817 characters)'
- fi
- chmod +x 'arp.c'
- fi # end of overwriting check
- echo shar: extracting "'README'" '(900 characters)'
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- sed 's/^X//' << \SHAR_EOF > 'README'
- X November, 1991
- X
- XThis is GETETHERS Version 1.0.
- X
- XGETETHERS runs through all the addresses on an ethernet (a.b.c.1 - a.b.c.254)
- Xand pings each address, and then determines the ethernet address for that host.
- XIt produces a list, either in ASCII or in the binary format for an Excelan
- XLanalyzer, of hostname/ethernet address pairs for all hosts on that network.
- X
- XThis program has been tested on Sun workstations under SunOS 4.1.1. It may
- Xwork on other systems with minor modifications, but I don't need it anywhere
- Xelse, and haven't tried. It could be easily modified to generate files for
- Xother ethernet analyzer products (e.g., Sniffer), but since we don't have
- Xany of those, I don't feel real motivated to do it.
- X
- XIf you make modifications or fixes, please send them to me for incorporation
- Xinto future versions.
- X
- XDave Curry
- XPurdue University
- XEngineering Computer Network
- Xdavy@ecn.purdue.edu
- SHAR_EOF
- if test 900 -ne "`wc -c < 'README'`"
- then
- echo shar: error transmitting "'README'" '(should have been 900 characters)'
- fi
- chmod +x 'README'
- fi # end of overwriting check
- echo shar: extracting "'excelan.c'" '(1748 characters)'
- if test -f 'excelan.c'
- then
- echo shar: will not over-write existing file "'excelan.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'excelan.c'
- X#ifndef lint
- Xstatic char *RCSid = "$Header: /usr/src/ecn/getethers/RCS/excelan.c,v 1.1 91/11/27 10:56:30 davy Exp $";
- X#endif
- X
- X/*
- X * excelan.c - routines to write lanalyzer files.
- X *
- X * David A. Curry
- X * Purdue University
- X * Engineering Computer Network
- X * davy@ecn.purdue.edu
- X * November, 1991
- X *
- X * $Log: excelan.c,v $
- X * Revision 1.1 91/11/27 10:56:30 davy
- X * Initial revision
- X *
- X */
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <net/if.h>
- X#include <netinet/in.h>
- X#include <netinet/if_ether.h>
- X#include <stdio.h>
- X#include "defs.h"
- X
- Xint nbytes; /* number of bytes written */
- X
- X/*
- X * excelan_header - put out the mysterious crap at the top of the file.
- X */
- Xexcelan_header(fp)
- XFILE *fp;
- X{
- X int i;
- X
- X fwrite(" \20L\0\01\01", 1, 6, fp);
- X fwrite("Excelan host name file", 1, 22, fp);
- X
- X for (i = 0; i < 52; i++)
- X fputc('\0', fp);
- X
- X fwrite("!\20\304\t", 1, 4, fp);
- X
- X nbytes = 84;
- X}
- X
- X/*
- X * excelan_entry - write out an ethernet address/hostname pair.
- X */
- Xexcelan_entry(h, fp)
- XHostInfo *h;
- XFILE *fp;
- X{
- X int i;
- X register char *p;
- X struct ether_addr *ea, *ether_aton();
- X
- X /*
- X * Magic.
- X */
- X fputc('\31', fp);
- X
- X /*
- X * Write the ethernet address.
- X */
- X ea = ether_aton(h->hl_ether);
- X fwrite(ea, 1, 6, fp);
- X
- X /*
- X * Put the hostname.
- X */
- X for (i=0, p=h->hl_name; (i < 18) && (*p != '.'); i++, p++)
- X fputc(*p, fp);
- X
- X /*
- X * Pad with nulls.
- X */
- X for (; i < 18; i++)
- X fputc('\0', fp);
- X
- X nbytes += 25;
- X}
- X
- X/*
- X * excelan_footer - pad the file to FILESIZE bytes.
- X */
- Xexcelan_footer(fp)
- XFILE *fp;
- X{
- X /*
- X * Put out the broadcast address.
- X */
- X fputc('\31', fp);
- X fwrite("\377\377\377\377\377\377", 1, 6, fp);
- X fwrite("BROADCAST\0", 1, 10, fp);
- X
- X nbytes += 17;
- X
- X /*
- X * Pad the file.
- X */
- X for (; nbytes < FILESIZE; nbytes++)
- X fputc('\0', fp);
- X}
- SHAR_EOF
- if test 1748 -ne "`wc -c < 'excelan.c'`"
- then
- echo shar: error transmitting "'excelan.c'" '(should have been 1748 characters)'
- fi
- chmod +x 'excelan.c'
- fi # end of overwriting check
- echo shar: extracting "'getethers.8l'" '(2415 characters)'
- if test -f 'getethers.8l'
- then
- echo shar: will not over-write existing file "'getethers.8l'"
- else
- sed 's/^X//' << \SHAR_EOF > 'getethers.8l'
- X.TH GETETHERS 8L "27 November 1991" "ECN"
- X.SH NAME
- Xgetethers \- get ethernet address/hostname information
- X.SH SYNOPSIS
- X.B getethers
- X[
- X.B \-v
- X] [
- X.B \-w
- X]
- X.I network
- X[
- X.IR network ...
- X]
- X.SH DESCRIPTION
- X.PP
- X.B getethers
- Xprobes the specified network(s),
- Xwhose addresses are given in Internet ``dot'' notation,
- Xand produces a list of host name and ethernet address pairs for each host
- Xon the network that responds to ICMP ECHO_REQUEST packets.
- XThe program assumes a subnet mask of 255.255.255.0 (0xffffff00),
- Xand does not probe host number 0 or host number 255,
- Xwhich are used as the broadcast address.
- X.PP
- XIf the
- X.B \-v
- Xoption is specified,
- Xa list is produced on the standard output that contains the host name,
- Xinternet address,
- Xand ethernet address of each host that responded to ICMP ECHO_REQUEST
- Xpackets.
- XIf the
- X.B \-w
- Xoption is specified,
- Xa file will be written for each network that can be used with the Excelan
- XLanalyzer product as a name-to-address translation file.
- XThe name of the file will be
- X.IR XXXnet.nam ,
- Xwhere
- X.I XXX
- Xis the last byte of the network address.
- X.PP
- X.B getethers
- Xworks by first probing the system's ethernet interfaces,
- Xlooking for the interface that is connected to the specified network.
- XIf the system is not connected to that network,
- X.B getethers
- Xprints an error message and goes on to the next network.
- XAfter discovering the proper interface,
- X.B getethers
- Xsends up to three ICMP ECHO_REQUEST packets to each host number on that
- Xnetwork from 1 to 254.
- XIf the host responds,
- X.B getethers
- Xthen searches the local host's arp table for the remote host's ethernet
- Xaddress.
- XIf the remote host does not respond to the ECHO_REQUEST packets within
- Xthree seconds,
- Xit is assumed to be down or non-existent,
- Xand is skipped.
- X.SH SEE ALSO
- X.BR arp (4P),
- X.BR arp (8C),
- X.BR etherfind (8C),
- X.BR ethers (3N),
- X.BR icmp (4P),
- X.BR inet (3N),
- X.BR nit (4P),
- X.BR ping (8C),
- X.BR rarpd (8C)
- X.SH BUGS
- X.PP
- XThe assumption of a 255.255.255.0 subnet mask,
- Xand the assumption of all-zero or all-ones as a broadcast address,
- Xare probably not good ideas and should be determined at run-time,
- Xbut it works in our environment.
- X.PP
- XThe Lanalyzer file,
- Xdue to its fixed size,
- Xcannot handle more than 100 entries.
- XIf a network has more than 100 hosts connected (and up),
- Xthe file will not be usable (or at least the stuff after 100 entries won't
- Xbe).
- X.SH AUTHOR
- XDavid A. Curry, Purdue University Engineering Computer Network
- SHAR_EOF
- if test 2415 -ne "`wc -c < 'getethers.8l'`"
- then
- echo shar: error transmitting "'getethers.8l'" '(should have been 2415 characters)'
- fi
- chmod +x 'getethers.8l'
- fi # end of overwriting check
- echo shar: done with directory "'getethers'"
- cd ..
- # End of shell archive
- exit 0
-